#include <string.h>
#include "sipsiparser.h"
#include "buildersectioncontrol.h"
#include "pluginbat.h"
#include "builderplugin.h"
#include "plugindvbfun.h"

#define MANUAL_SCAN_RECV_BAT_PROCESS 10

typedef enum
{
	PLUGIN_MANUAL_STATUS_IDLE,
	PLUGIN_MANUAL_STATUS_WAIT_LOCK,
	PLUGIN_MANUAL_STATUS_RECV_SIPSI,
	PLUGIN_MANUAL_STATUS_RECV_BAT,
}PLUGIN_MANUAL_STATUS_T;

typedef struct
{
	PLUGIN_MANUAL_STATUS_T			m_eStatus;
	builder_tuner_t					m_stCurTuner;
	unsigned int						m_u32Process;
	builder_section_control_t			m_stSecCtrl;
	builder_bat_control_t				m_stBatRecvCtrl;
	unsigned int						m_u32DataOK;
	unsigned int						m_u32TimeOut;
}plugin_manual_search_t;

plugin_manual_search_t pstManualCtrl = {PLUGIN_MANUAL_STATUS_IDLE};

int PluginManualSearchReset()
{
	int s32Ret = -1;

	PluginDvbLogcat("PluginManualSearchReset() - entry\r\n");
	
	pstManualCtrl.m_u32DataOK = 0;
	pstManualCtrl.m_u32Process = 0;
	pstManualCtrl.m_u32TimeOut = 0;
	pstManualCtrl.m_eStatus = PLUGIN_MANUAL_STATUS_IDLE;
	s32Ret = PluginSectionDataStop(&pstManualCtrl.m_stSecCtrl);
	s32Ret = PluginBatStop(&pstManualCtrl.m_stBatRecvCtrl);
	
	PluginDvbLogcat("PluginManualSearchReset() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;	
}

int PluginManaulSearchStart(builder_manual_search_t* pstParam)
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginManaulSearchStart() - entry, pstParam = %p\r\n", pstParam);
	if(pstParam && pstManualCtrl.m_eStatus==PLUGIN_MANUAL_STATUS_IDLE)
	{
		s32Ret = PluginCheckTunerInfo(&pstParam->m_stTunerInfo);
		if(0 == s32Ret)
		{
			memcpy(&pstManualCtrl.m_stCurTuner, &pstParam->m_stTunerInfo, sizeof(builder_tuner_t));
			s32Ret = PluginDvbTunerLock(&pstManualCtrl.m_stCurTuner);
			pstManualCtrl.m_u32Process = 0;
			pstManualCtrl.m_eStatus = PLUGIN_MANUAL_STATUS_WAIT_LOCK;
			pstManualCtrl.m_u32TimeOut = 2;//lock time out 2s
		}
		else
		{
			PluginDvbLogcat("PluginManaulSearchStart() - check tuner info error\r\n");
			s32Ret = -1;
		}
	}
	else
	{
		PluginDvbLogcat("PluginManaulSearchStart() - error param or stage, pstParam = %p, pstManualCtrl.m_eStatus = %d\r\n", pstParam, pstManualCtrl.m_eStatus);
	}
	PluginDvbLogcat("PluginManaulSearchStart() - return, s32Ret = %d\r\n", s32Ret);

	return s32Ret;
}

int PluginManualSearchTick()
{
	int s32Ret = -1;
	unsigned int u32Process = 0;

	PluginDvbLogcat("PluginManualSearchTick() - entry\r\n");
	if(pstManualCtrl.m_eStatus == PLUGIN_MANUAL_STATUS_RECV_SIPSI)
	{
		s32Ret = PluginSectionDataTick(&pstManualCtrl.m_stSecCtrl);
		if(s32Ret == -1)
		{
			pstManualCtrl.m_eStatus = PLUGIN_MANUAL_STATUS_IDLE;
			pstManualCtrl.m_u32DataOK = 0;
			pstManualCtrl.m_u32Process = SCAN_ALL_PROCESS;
			s32Ret = PluginSectionDataStop(&pstManualCtrl.m_stSecCtrl);
		}
		else if(s32Ret == 1)//data ok, but some prog pmt timeout
		{
			PluginSectionDataGetProcess(&pstManualCtrl.m_stSecCtrl, &u32Process);
			pstManualCtrl.m_u32Process = MANUAL_SCAN_LOCK_PROCESS + (u32Process*(MANUAL_SCAN_SIPSI_PROCESS)/SCAN_ALL_PROCESS);//section control 90%, tuner lock 10%
			if(pstManualCtrl.m_u32Process == 100)
			{
				pstManualCtrl.m_u32DataOK = 1;
				pstManualCtrl.m_eStatus = PLUGIN_MANUAL_STATUS_IDLE;
			}
			s32Ret = 0;
		}
	}
	else if(pstManualCtrl.m_eStatus == PLUGIN_MANUAL_STATUS_RECV_BAT)
	{
		s32Ret = PluginBatTick(&pstManualCtrl.m_stBatRecvCtrl);
		if(s32Ret == -1)
		{
			PluginDvbLogcat("PluginManualSearchTick() - receive BAT time out\r\n");
			pstManualCtrl.m_u32Process = 100;
			pstManualCtrl.m_u32DataOK = 1;
			pstManualCtrl.m_eStatus = PLUGIN_MANUAL_STATUS_IDLE;
		}
	}
	else if(pstManualCtrl.m_eStatus == PLUGIN_MANUAL_STATUS_WAIT_LOCK)
	{
		s32Ret = 0;
		if(pstManualCtrl.m_u32TimeOut > 0)
		{
			pstManualCtrl.m_u32TimeOut--;
			if(pstManualCtrl.m_u32TimeOut == 0)
			{
				PluginDvbLogcat("PluginManualSearchTick() - tuner lock time out\r\n");
				s32Ret = -1;
				pstManualCtrl.m_u32Process = 100;
				pstManualCtrl.m_u32DataOK = 0;
				pstManualCtrl.m_eStatus = PLUGIN_MANUAL_STATUS_IDLE;
			}
		}
	}
	PluginDvbLogcat("PluginManualSearchTick() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;	
	
}

int PluginManualSearchLockFinish(builder_tuner_t* pstTunerInfo, unsigned int u32Lock)
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginManualSearchLockFinish() - entry, pstTunerInfo = %p, u32Lock = %d\r\n", pstTunerInfo, u32Lock);
	if(pstTunerInfo && pstManualCtrl.m_eStatus==PLUGIN_MANUAL_STATUS_WAIT_LOCK)
	{
		if(u32Lock == 1)
		{
			builder_section_control_cfg_t stCfg;
			stCfg.m_eSecRecvCfg = BUILDER_SECTION_DATA_NOSDT_CONTINUE;
			stCfg.m_u16PSITimeoutRatio = 9;
			stCfg.m_u16SITimeoutRatio = 2;
			PluginSectionDataSetConfig(&pstManualCtrl.m_stSecCtrl, &stCfg);
			
			pstManualCtrl.m_u32TimeOut = 4;
			s32Ret = PluginSectionDataReset(&pstManualCtrl.m_stSecCtrl);
			if(s32Ret == 0)
			{
				s32Ret = PluginSectionDataStart(&pstManualCtrl.m_stSecCtrl);
				pstManualCtrl.m_eStatus = PLUGIN_MANUAL_STATUS_RECV_SIPSI;
				pstManualCtrl.m_u32Process = MANUAL_SCAN_LOCK_PROCESS;
			}
			else
			{
				PluginDvbLogcat("PluginManualSearchLockFinish() - start recv sdt error\r\n");
				pstManualCtrl.m_eStatus = PLUGIN_MANUAL_STATUS_IDLE;
				pstManualCtrl.m_u32Process = SCAN_ALL_PROCESS;
			}
		}
		else
		{
			PluginDvbLogcat("PluginManualSearchLockFinish() - u32Lock = 0, pstTunerInfo->m_u32Freq = %d\r\n", pstTunerInfo->m_u32Freq);
			s32Ret = 0;
			pstManualCtrl.m_eStatus = PLUGIN_MANUAL_STATUS_IDLE;
			pstManualCtrl.m_u32Process = SCAN_ALL_PROCESS;
		}
	}
	PluginDvbLogcat("PluginManualSearchLockFinish() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;	
}

int PluginManualSearchHandleDataRecved(unsigned char* pu8Data, unsigned int hFilter)
{
	int s32Ret = -1;
	unsigned int u32Process;

	PluginDvbLogcat("PluginManualSearchHandleDataRecved() - entry, pu8Data = %p, hFilter = %x\r\n", pu8Data, hFilter);
	if(pu8Data && pstManualCtrl.m_eStatus==PLUGIN_MANUAL_STATUS_RECV_SIPSI)
	{
		pstManualCtrl.m_u32TimeOut = 4;
		s32Ret = PluginSectionDataRecv(&pstManualCtrl.m_stSecCtrl, hFilter, pu8Data);
		if(s32Ret == 0)
		{
			s32Ret = PluginSectionDataGetProcess(&pstManualCtrl.m_stSecCtrl, &u32Process);
			if(s32Ret == 0)
			{
				pstManualCtrl.m_u32Process = MANUAL_SCAN_LOCK_PROCESS + (u32Process*(MANUAL_SCAN_SIPSI_PROCESS - MANUAL_SCAN_RECV_BAT_PROCESS)/SCAN_ALL_PROCESS);//section control 80%, tuner lock 10%, bat 10%
				if(u32Process == 100)
				{
					PluginBatReset(&pstManualCtrl.m_stBatRecvCtrl);
					s32Ret = PluginBatStart(&pstManualCtrl.m_stBatRecvCtrl);
					pstManualCtrl.m_eStatus = PLUGIN_MANUAL_STATUS_RECV_BAT;
					pstManualCtrl.m_u32TimeOut = 0;
				}
			}
			else
			{
				PluginDvbLogcat("PluginManualSearchHandleDataRecved() - get section control process not OK\r\n");
			}
		}
		else
		{
			PluginDvbLogcat("PluginManualSearchHandleDataRecved() - send to section control not OK\r\n");
			s32Ret = 0;
		}
	}
	else if(pu8Data && pstManualCtrl.m_eStatus==PLUGIN_MANUAL_STATUS_RECV_BAT)
	{
		s32Ret = PluginBatRecv(&pstManualCtrl.m_stBatRecvCtrl, hFilter, pu8Data);
		if(s32Ret == -1)
		{
			PluginDvbLogcat("PluginManualSearchHandleDataRecved() - PluginBatRecv error\r\n");
			pstManualCtrl.m_u32Process = 100;
			pstManualCtrl.m_u32DataOK = 1;
			//pstManualCtrl.m_eStatus = PLUGIN_MANUAL_STATUS_IDLE;
			PluginBatStop(&pstManualCtrl.m_stBatRecvCtrl);
		}
		else
		{
			PluginBatGetProcess(&pstManualCtrl.m_stBatRecvCtrl, &u32Process);
			pstManualCtrl.m_u32Process = 100 - MANUAL_SCAN_RECV_BAT_PROCESS + (u32Process*MANUAL_SCAN_RECV_BAT_PROCESS)/100;//section control 80%, tuner lock 10%, bat 10%
			if(u32Process == 100)
			{
				//s32Ret = PluginBatStop(&pstManualCtrl.m_stBatRecvCtrl);
				pstManualCtrl.m_u32Process = 100;
				pstManualCtrl.m_u32DataOK = 1;
				//pstManualCtrl.m_eStatus = PLUGIN_MANUAL_STATUS_IDLE;
			}
		}
	}
	PluginDvbLogcat("PluginManualSearchHandleDataRecved() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

int PluginManualGetSearchData(builder_ts_t* pstTs, builder_service_t* pstServices, unsigned int* pu32ServiceCnt, builder_section_t** ppstBat, builder_section_t** ppstNit)
{
	int s32Ret = -1;
	builder_ts_t stTs;
	builder_service_t astServices[BUILDER_MAX_PROG_PER_TS];
	unsigned int u32ServiceCnt = 0;
	
	PluginDvbLogcat("PluginManualGetSearchData() - entry, pstTs = %p, pstServices = %p, pu32ServiceCnt = %p, pstBat = %p, pstNit = %p\r\n", pstTs, pstServices, pu32ServiceCnt, ppstBat, ppstNit);
	if(pstManualCtrl.m_u32DataOK == 1 && pstManualCtrl.m_eStatus==PLUGIN_MANUAL_STATUS_RECV_BAT)
	{
		memset(&stTs, 0, sizeof(stTs));
		s32Ret = PluginSectionDataGetSections(&pstManualCtrl.m_stSecCtrl, &stTs.m_stSiPsi);
		if(s32Ret == 0)
		{
			if(stTs.m_stSiPsi.m_pstPat && stTs.m_stSiPsi.m_pstPmt)
			{
				memcpy(&stTs.m_stTuner, &pstManualCtrl.m_stCurTuner, sizeof(stTs.m_stTuner));
				s32Ret = PluginParseTs(&stTs, astServices, &u32ServiceCnt);
				if(s32Ret == 0)
				{
					memcpy(pstTs, &stTs, sizeof(stTs));
					*pu32ServiceCnt = u32ServiceCnt;
					memcpy(pstServices, astServices, u32ServiceCnt*sizeof(builder_service_t));
				}
				else
					PluginDvbLogcat("PluginManualGetSearchData() - PluginParseTs error\r\n");
			}
		}

		*ppstBat = NULL;
		PluginBatGetSections(&pstManualCtrl.m_stBatRecvCtrl, ppstBat);
		
		pstManualCtrl.m_u32DataOK = 0;
		pstManualCtrl.m_eStatus = PLUGIN_MANUAL_STATUS_IDLE;
	}
	else
	{
		PluginDvbLogcat("PluginManualGetSearchData() - stage error\r\n");
	}
	
	PluginDvbLogcat("PluginManualGetSearchData() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

int PluginManualGetProcess(unsigned int* pu32DataOk, unsigned int* pu32Process)
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginManualGetProcess() - entry, pu32DataOk = %p, pu32Process = %p\r\n", pu32DataOk, pu32Process);
	if(pu32DataOk && pu32Process)
	{
		*pu32DataOk = pstManualCtrl.m_u32DataOK;
		*pu32Process = pstManualCtrl.m_u32Process;
		if(*pu32Process == SCAN_ALL_PROCESS && *pu32DataOk == 0)
			pstManualCtrl.m_eStatus = PLUGIN_MANUAL_STATUS_IDLE;
		s32Ret = 0;
	}
	PluginDvbLogcat("PluginManualGetProcess() - return, s32Ret = %d\r\n", s32Ret);
	
	return s32Ret;		
}

